import { IsAdmin, IsAdminOrStaff, IsCopilot, IsLogin, IsUser } from '$/permissions'
import type { RouteCTL } from '@/types'
import { createRouter, createWebHistory, type NavigationGuardWithThis } from 'vue-router'
import { aurls, curls, urls, uurls } from './urls'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      meta: { name: '登录' },
      component: () => import('@/views/EntranceView.vue')
    },
    {
      path: aurls.index,
      meta: { name: '管理端首页' },
      redirect: aurls.order,
      beforeEnter: routeCtl({ auth: [IsLogin, IsAdminOrStaff], backPath: urls.index }),
      component: () => import('@/views/admin/HomeView.vue'),
      children: [
        {
          path: aurls.admin,
          meta: { name: '管理员管理' },
          beforeEnter: [routeCtl({ auth: [IsAdmin], backPath: urls.s403 })],
          component: () => import('@/views/admin/AdminView.vue')
        },
        {
          path: aurls.copilot,
          meta: { name: '陪玩管理' },
          component: () => import('@/views/admin/CopilotView.vue')
        },
        {
          path: aurls.user,
          meta: { name: '用户管理' },
          component: () => import('@/views/admin/UserView.vue')
        },
        {
          path: aurls.topup,
          meta: { name: '充值订单' },
          component: () => import('@/views/admin/TopupView.vue')
        },
        {
          path: aurls.order,
          meta: { name: '订单管理' },
          component: () => import('@/views/admin/OrderView.vue')
        },
        {
          path: aurls.log,
          meta: { name: '操作日志' },
          beforeEnter: routeCtl({ auth: [IsAdmin], backPath: urls.s403 }),
          component: () => import('@/views/admin/LogView.vue')
        },
        {
          path: aurls.settings,
          meta: { name: '设置' },
          component: () => import('@/views/admin/SettingsView.vue')
        }
      ]
    },
    {
      path: uurls.index,
      meta: { name: '客户端首页' },
      redirect: uurls.copilot,
      beforeEnter: routeCtl({ auth: [IsLogin, IsUser], backPath: urls.index }),
      component: () => import('@/views/user/HomeView.vue'),
      children: [
        {
          path: uurls.copilot,
          meta: { name: '陪玩' },
          component: () => import('@/views/user/CopilotView.vue')
        },
        {
          path: uurls.star,
          meta: { name: '收藏夹' },
          component: () => import('@/views/user/StarView.vue')
        },
        {
          path: uurls.copilotDetail,
          meta: { name: '陪玩详情页' },
          component: () => import('@/views/user/CopilotDetailView.vue')
        },
        {
          path: uurls.topup,
          meta: { name: '充值' },
          component: () => import('@/views/user/TopupView.vue')
        },
        {
          path: uurls.order,
          meta: { name: '订单' },
          component: () => import('@/views/user/OrderView.vue')
        },
        {
          path: uurls.settings,
          meta: { name: '设置' },
          component: () => import('@/views/user/SettingsView.vue')
        }
      ]
    },
    {
      path: curls.index,
      meta: { name: '陪玩端首页' },
      redirect: curls.comment,
      beforeEnter: routeCtl({ auth: [IsLogin, IsCopilot], backPath: urls.index }),
      component: () => import('@/views/copilot/HomeView.vue'),
      children: [
        {
          path: curls.comment,
          meta: { name: '评论' },
          component: () => import('@/views/copilot/CommentView.vue')
        },
        {
          path: curls.order,
          meta: { name: '订单' },
          component: () => import('@/views/copilot/OrderView.vue')
        },
        {
          path: curls.settings,
          meta: { name: '设置' },
          component: () => import('@/views/copilot/SettingsView.vue')
        }
      ]
    },
    {
      path: urls.s404,
      component: () => import('@/views/NotFoundView.vue')
    },
    {
      path: urls.s403,
      component: () => import('@/views/ForbiddenView.vue')
    }
  ]
})

router.beforeEach((to, _, next) => {
  if (to.matched.length === 0) {
    return next(urls.s404)
  }
  next()
})

function routeCtl({ auth, backPath, nextPath }: RouteCTL = {}): NavigationGuardWithThis<undefined> {
  return async (_, __, next) => {
    if (!auth) return next()
    const $auth = auth.some((e) => e())
    const path = $auth ? nextPath : backPath
    if (!path) return next()
    return next(router.resolve(path))
  }
}

export default router
